These exercises are meant to supplement the lecture notes based on Jack VanderPlas's excellent book as well as material from http://introtopython.org.
You are encouraged to modify your local version of this iPython notebook. Please add in any additional comments or advice you found helpful and definitely try to experiment with new code!
Before we begin, we need to run this code block to ensure the code is compatible between Python 2 and 3.
In [ ]:
# Ensures compatibility between Python 2 and 3.
from __future__ import print_function, division
from __builtin__ import range
Let's quickly go through some basics of variable assignment.
In [ ]:
print('Hello Python world!')
Try to get the following code to print the same message as the one above.
In [ ]:
...
print(message)
In [ ]:
# Example of two strings.
my_string = "This is a double-quoted string."
your_string = 'This is a single-quoted string.'
# Example of types.
quote = "Josh once asked, 'Is this distinction useful?'"
followup = 'What do you think?'
We now want to manipulate these strings. A few exercises are below. Take as much time as you need; you are not expected to be able to complete them all.
In [ ]:
# Combine the two lines (`quote`, `followup`) into one string with appropriate spacing.
combined_quote = ...
print(quote, followup) # printing two strings
print(combined_quote) # print the combined string
In [ ]:
# Check whether the two strings are identical.
s1, s2 = "Test.", 'Test.'
same = ...
print(same)
In [ ]:
# Split `my_string` into a separate string for each word.
collection_of_strings = ...
print(collection_of_strings)
In [ ]:
# Check whether the *letter* `a` is in `quote`.
a_lettercheck = ...
print(a_lettercheck)
In [ ]:
# Check whether the *word* `a` is in `quote`.
a_wordcheck = ...
print(a_wordcheck)
While you can define some variables explicitly, Python defines many of them implicitly and can change them when doing math. This mostly matters when working with integers and floats.
In [ ]:
# Define two variables.
a, b, c = 3, 2, 5.
print('a = {0}'.format(a))
print('b =', b)
print('c', '=', c)
Let's see this in action below.
In [ ]:
# Addition.
x = a + b
print(x, type(x))
# Subtraction.
x = c - a
print(x, type(x))
# Multiplication.
x = b * a
print(x, type(x))
# Division.
x = a / b
print(x, type(x))
# Exponentiation.
x = c ** b
print(x, type(x))
In [ ]:
# ???
x = b // a
print(x, type(x))
x = c // a
print(x, type(x))
This type of distinction matters because roundoff errors can be an issue. These are a humongous pain but can be dealt with once you know what to watch out for.
In [ ]:
f1, f2 = 0.3, 0.1 + 0.2
f1, f2, f1 == f2 # leaving variables for auto-output
Note that everything in Python is at some level an object. Our variables are no exception.
In [ ]:
f1.as_integer_ratio(), f2.as_integer_ratio(), (0.5).as_integer_ratio()
Magnitudes are a pretty common unit in astronomy and are defined in terms of $m \equiv -2.5 \log(F)$ where $F$ is in units of flux density (energy/area/time/frequency).
Compute $m$ given $F = b(a-1)^2 + c(a-1) + 5$. Note that not all math operations are included in Python by default.
In [ ]:
# Compute magnitude given flux.
F = ...
m = ...
print(m)
We can keep track of many objects simultaneously by using lists.
In [ ]:
dogs = ['border collie', 'australian cattle dog', 'labrador retriever']
Now let's print out an element of the list and capitalize it. We can figure out how to do this within the notebook by taking advantage of tab completion.
In [ ]:
# Access element.
dog = dogs[0]
# Print result.
print(dog.)
See if you can figure out how to find where 'australian cattle dog' is located using just standard Python operators and built-in list functions.
In [ ]:
# Searching list.
dogs.index(...)
As before, see if you can figure out how to append items to the end of a list or insert them in the middle of a list. Append 'poodle' to the end of the list, then insert 'chihuahua' after 'border collie' without entering the position by hand.
In [ ]:
# Append.
# Insert.
print(dogs)
Now change border collie to 'maltese' and remove 'labrador retriever' from the list.
In [ ]:
# Remove element.
dogs.remove(...)
dogs[0] = '...'
print(dogs)
Finally, a hugely useful concept in Python is slicing objects, where we can return only relevant portions of an object without modifying the relevant object itself.
In [ ]:
# Slice an array
print(dogs[1:3])
print(dogs)
Like lists, tuples can keep track of many items at once. However, unlike lists, they're static and can't be changed after initialization.
In [ ]:
date = (6, 11, 2018)
In [ ]:
# Check tomorrow's date.
Why might we want to use tuples instead of lists?
Dictionaries are extremely flexible mappings of keys to values, and form the basis of much of Python's internal implementation. They are again another alternative to lists.
In [ ]:
# Initialize dictionary.
numbers = {'one': 1, 'two': 2, 'three': 3}
# Access a value using its key.
print(numbers['two'])
# Add a new element.
numbers['ninety'] = 90
print(numbers)
Note that dictionaries do not maintain any sense of order for the input parameters. This is by design, since this lack of ordering allows dictionaries to be implemented very efficiently.
Sets contain unordered collections of unique items only. It is really fast to perform bulk quick checks but can be hard to search. They are most useful for union, intersection, difference, symmetric difference math operations, and others. Python's sets have all of these operations built-in, via methods or operators.
In [ ]:
primes = {2, 3, 5, 7}
odds = {1, 3, 5, 7, 9}
# Union: items appearing in either
print(primes.union(odds)) # equivalently with a method
# Intersction
{1, 2, 3, 5, 7, 9}
print(primes.intersection(odds)) # equivalently with a method
# difference: Items in primes but not in odds
print(primes.difference(odds)) # equivalently with a method
Python's conditional statements are pretty straightforrward.
In [ ]:
x = -15
if x == 0:
print(x, "is zero")
elif x > 0:
print(x, "is positive")
elif x < 0:
print(x, "is negative")
else:
print(x, "is unlike anything I've ever seen...")
Python is able to work with any type of iterable, not just integers. This gives loops a lot more flexibility.
In [ ]:
# Traditional loop.
for i in range(3):
print('I like ' + dogs[i] + 's.')
# "Pythonic" loop.
for dog in dogs:
print('I like ' + dog + 's.')
This flexibility makes loops in Python incredibly powerful. As an example, see if you can get the loop below to run using some combination of (1) range, (2) zip, and (3) enumerate.
In [ ]:
for ... in ...:
print(counter, ':', dog)
Alternately, we can use while loops to get things done.
In [ ]:
i = 0
while i < len(dogs):
print(i, ':', dogs[i])
i += 1
Beware (re-)assigning things without warning! Python by default only "protects" a certain subset of objects by automatically copying them.
In [ ]:
# Example 1.
josh = quote # reassign
josh += " He got #rekt." # ???
print(quote)
print(josh)
# Example 2.
quotes = quote.split() # reassign
josh = quotes
josh += " He got #rekt.".split() # ???
print(quotes)
print(josh)
# Example 3.
quotes = quote.split() # reassign
josh = quotes[:]
josh += " He got #rekt.".split() # ???
print(quotes)
print(josh)
# Example 4.
d = b
d += 3.
print(b)
print(d)
Finally, now that our code is becoming slightly longer, let's take a step back and talk about good coding practices. Some of these are coded into Python itself.
In [ ]:
import this
In addition, there's also the PEP8 style guide.
Starting here.
Starting with the following variables:
In [ ]:
title = "Banneker + Aztlan Initiative"
month = 6
day = 11
year = 2018
width = 30
1) Write out the date in the following formats using the above variables:
a) Note that the month is "zero-padded" ('06', instead of just '6'):
2018/06/11
b) Note that only the last two digits of the year are shown:
06/11/18
title'Print out the following string using the title variable and without manually typing more than a single '=' character:
Banneker + Aztlan Initiative
============================
Hint: Not only can you add two strings together (i.e. abc + def), but you can also multiple a string by an integer - try it!